package com.waypolice.manager.controller;

import com.waypolice.common.constant.CmsResult;
import com.waypolice.manager.component.ActivitiAppointTask;
import com.waypolice.manager.component.ActivitiComponent;
import com.waypolice.manager.service.ActDefineService;
import com.waypolice.pojo.UpmsActDefine;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.*;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * 描述:
 *
 * @author zyp
 * @description 工作流单独的控制层
 * @create 2019-03-20 11:53
 */
@Controller
@RequestMapping(value = "/activiti/common")
@Api(value = "工作流公共controller", description = "输出追踪流信息、读取带跟踪的图片、读取资源，通过流程ID")
public class ActivitiAction {

    private static final Logger logger = LoggerFactory.getLogger(ActivitiAction.class);

    @Autowired
    protected RuntimeService runtimeService;

    @Autowired
    protected TaskService taskService;

    @Autowired
    protected HistoryService historyService;

    @Autowired
    protected RepositoryService repositoryService;

    @Autowired
    private IdentityService identityService;

    @Autowired
    private ProcessEngineFactoryBean processEngine;

    @Autowired
    private ProcessEngineConfiguration processEngineConfiguration;

    @Autowired
    private ActivitiComponent activitiComponent;

    @Autowired
    private ActDefineService actDefineService;

    @Autowired
    private ActivitiAppointTask activitiAppointTask;

    /**
     * @author:zyp
     * @description 输出追踪流信息
     * @date: 2019/3/20 11:56
     * @return 
     */
    @ApiOperation(value = "输出追踪流信息")
    @RequestMapping(value = "/findProcess")
    @ResponseBody
    public List<Map<String, Object>> traceProcess(@RequestParam("pid") String processInstanceId) throws Exception {
        List<Map<String, Object>> activityInfos = activitiComponent.traceProcess(processInstanceId);
        return activityInfos;
    }


    /**
     * @author:zyp
     * @description 读取带跟踪的图片
     * @date: 2019/3/20 11:56
     * @return 
     */
    @RequestMapping(value = "/findProcessImg/{executionId}")
    public void readResource(@PathVariable("executionId") String executionId, HttpServletResponse response)
            throws Exception {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(executionId).singleResult();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        List<String> activeActivityIds = runtimeService.getActiveActivityIds(executionId);
        // 不使用spring请使用下面的两行代码
//    ProcessEngineImpl defaultProcessEngine = (ProcessEngineImpl) ProcessEngines.getDefaultProcessEngine();
//    Context.setProcessEngineConfiguration(defaultProcessEngine.getProcessEngineConfiguration());

        // 使用spring注入引擎请使用下面的这行代码
        processEngineConfiguration = processEngine.getProcessEngineConfiguration();
        Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);

        ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
        InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds);

        // 输出资源内容到相应对象
        byte[] b = new byte[1024];
        int len;
        while ((len = imageStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }

    /**
     * @author:zyp
     * @description 读取资源，通过流程ID
     * @date: 2019/3/20 13:33
     * @return 
     */
    @RequestMapping(value = "/process-instance")
    public void loadByProcessInstance(@RequestParam("type") String resourceType, @RequestParam("pid") String processInstanceId, HttpServletResponse response)
            throws Exception {
        InputStream resourceAsStream = null;
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId())
                .singleResult();

        String resourceName = "";
        if (resourceType.equals("image")) {
            resourceName = processDefinition.getDiagramResourceName();
        } else if (resourceType.equals("xml")) {
            resourceName = processDefinition.getResourceName();
        }
        resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
        byte[] b = new byte[1024];
        int len = -1;
        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }

    /**
     * @author:zyp
     * @description 根据当前运行的工作流程获取 流程中第一个执行的taskUser是否为指派关系
     * @date: 2019/3/27 18:07
     * @return
     */
    @RequestMapping(value = "/selectFirstTaskUser/{activitiType}/{trem}")
    @ResponseBody
    public Object selectFirstTaskUser(@PathVariable("activitiType") String activitiType,
                                      @PathVariable("trem") String trem,
                                      HttpServletResponse response){
        //获取当前借阅的最新的流程
        UpmsActDefine upmsActDefine = actDefineService.getNewAct(activitiType);
        if(upmsActDefine==null){
            return new CmsResult(0,"检索失败，请找系统管理员确认流程是否定义",0);
        }
        //获取流程的唯一标识
        String key = upmsActDefine.getAdKey();
        Object result = activitiAppointTask.getFirstTaks(key,trem);
        return result;
    }
    
    /**
     * @author:zyp
     * @description 获取下一个任务的审核人
     * @date: 2019/3/28 10:02
     * @return 
     */
    @RequestMapping(value = "/selectNextTaskUser/{taskId}")
    @ResponseBody
    public Object selectNextTaskUser(@PathVariable("taskId") String taskId, HttpServletResponse response){
        Object result = activitiAppointTask.appointTask(taskId);
        return result;
    }
}